<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Console\Tester;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\StreamOutput;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class CommandTester {
	private $command;
	private $input;
	private $output;
	
	/**
	 * Constructor.
	 *
	 * @param Command $command A Command instance to test.
	 */
	public function __construct(Command $command) {
		$this->command = $command;
	}
	
	/**
	 * Executes the command.
	 *
	 * Available options:
	 *
	 * * interactive: Sets the input interactive flag
	 * * decorated:   Sets the output decorated flag
	 * * verbosity:   Sets the output verbosity flag
	 *
	 * @param array $input   An array of arguments and options
	 * @param array $options An array of options
	 *
	 * @return integer The command exit code
	 */
	public function execute(array $input, array $options = array()) {
		$this->input = new ArrayInput( $input );
		if( isset( $options['interactive'] ) ) {
			$this->input->setInteractive( $options['interactive'] );
		}
		
		$this->output = new StreamOutput( fopen( 'php://memory', 'w', false ) );
		if( isset( $options['decorated'] ) ) {
			$this->output->setDecorated( $options['decorated'] );
		}
		if( isset( $options['verbosity'] ) ) {
			$this->output->setVerbosity( $options['verbosity'] );
		}
		
		return $this->command->run( $this->input, $this->output );
	}
	
	/**
	 * Gets the display returned by the last execution of the command.
	 *
	 * @return string The display
	 */
	public function getDisplay() {
		rewind( $this->output->getStream() );
		
		return stream_get_contents( $this->output->getStream() );
	}
	
	/**
	 * Gets the input instance used by the last execution of the command.
	 *
	 * @return InputInterface The current input instance
	 */
	public function getInput() {
		return $this->input;
	}
	
	/**
	 * Gets the output instance used by the last execution of the command.
	 *
	 * @return OutputInterface The current output instance
	 */
	public function getOutput() {
		return $this->output;
	}
}
